package com.my.aslife.gateway.filter;

import cn.hutool.json.JSONUtil;
import com.my.aslife.exception.BusinessException;
import com.my.aslife.module.common.*;
import com.my.aslife.module.entity.User;
import com.my.aslife.service.IUserService;
import com.my.aslife.utils.AppJwtUtil;
import com.my.aslife.utils.MyCheckUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @author mayuan
 * @description TODO
 */
@Component
@Slf4j
public class FrontendGlobalCheckTokenFilter implements Ordered, Filter {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IUserService userService;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        servletResponse.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("text/html; charset=UTF-8");

        // 获取请求路径
        String requestPath = request.getServletPath();
        log.info("请求路径 ==> {}",requestPath);
        String ip = request.getRemoteAddr();
        log.info("请求 IP  ==> {}", ip);
        ip = ip.replace(":","_");
        stringRedisTemplate.opsForValue().increment(RedisConstant.IP_ADDRESS + ip,1);

        String[] splitRequestPath = requestPath.split("/");

        // 放行登录、注册路径 login register
        boolean checkLoginPath = MyCheckUtils.checkLoginPath(splitRequestPath);
        if (checkLoginPath) {
            // 记录当期请求IP
            IPThreadLocal.setGlobalIP(ip);
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        String token = request.getHeader("token");
        log.info("token ==> {}", token);

        //4.判断token是否存在
        if(StringUtils.isBlank(token)){
            log.error("当前token不存在!");
            servletResponse.getWriter().write(JSONUtil.toJsonStr(ResponseResult.failed(ErrorCode.ILLEGAL_LOGIN)));
            return;
        }

        //5.判断token是否有效
        try {
            Claims claimsBody = AppJwtUtil.getClaimsBody(token);
            if (claimsBody == null) {
                servletResponse.getWriter().write(JSONUtil.toJsonStr(ResponseResult.failed(ErrorCode.TOKEN_IS_ILLEGAL)));
                return;
            }
            //是否是过期
            int result = AppJwtUtil.verifyToken(claimsBody);
            if(result == 1 || result  == 2) {
                log.error("当前token已经过期!");
                servletResponse.getWriter().write(JSONUtil.toJsonStr(ResponseResult.failed(ErrorCode.TOKEN_NOT_FOUND)));
                return;
            }

            Object userId = claimsBody.get("id");
            UserIdThreadLocal.save((Integer) userId);
            log.info("操作者id ==> {}", UserIdThreadLocal.get());

        } catch (Exception e) {
            e.printStackTrace();
            servletResponse.getWriter().write(JSONUtil.toJsonStr(ResponseResult.failed(ErrorCode.ILLEGAL_LOGIN)));
            return;
        }
        // 记录上传文件类型
        String uploadType = request.getHeader("type");
        if (!StringUtils.isBlank(uploadType)) {
            UploadTypeThreadLocal.setUploadType(uploadType);
        }
        // 记录 orderId
        String orderId = request.getHeader("orderId");
        if (orderId != null) {
            OrderIdThreadLocal.save(orderId);
            log.info("订单id ==> {}", orderId);
        }

        // 记录当期请求IP
        IPThreadLocal.setGlobalIP(ip);
        // 驳回违规账号
        User user = userService.queryUserById(UserIdThreadLocal.get());

        if (user.getStatus() == 1) {
            servletResponse.getWriter().write(JSONUtil.toJsonStr(ResponseResult.failed(ErrorCode.FAIL_LOGIN_ILLEGAL)));
            return;
        }

        // 放行正确的token
        filterChain.doFilter(request, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
